Micron Document
C.S.Burner 🪙 ━►🔥GIT Node

Node / reticulum_mirror / MeshChatX / files / tests / backend / test_database_auto_recover.py

Displaying Raw • Download

tests/backend/test_database_auto_recover.py dev (c9f60cc5) Text, 5.19 KB

T8b949e# SPDX-License-Identifier: 0BSD

T8b949e"""Tests for automatic database recovery backup selection."""

Tff7b72from T7ee787__future__ Tff7b72import Te6edf3annotations

Tff7b72import T7ee787os

Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787database Tff7b72import Te6edf3DatabaseTb4b4b4, Te6edf3PRE_MIGRATE_BACKUP_PREFIX
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787databaseT7ee787.T7ee787auto_recover Tff7b72import Tb4b4b4(
Te6edf3infer_version_hint_from_backup_nameTb4b4b4,
Te6edf3pick_compatible_backupTb4b4b4,
Te6edf3probe_backup_zipTb4b4b4,
Te6edf3run_auto_database_recoverTb4b4b4,
Te6edf3schema_version_restorableTb4b4b4,
Tb4b4b4)
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787databaseT7ee787.T7ee787schema Tff7b72import Te6edf3DatabaseSchema


Tff7b72def Td2a8fftest_schema_version_restorable_boundsTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3latest Tff7b72= Te6edf3DatabaseSchemaTff7b72.Td2a8ffLATEST_VERSION
Tff7b72assert Te6edf3schema_version_restorableTb4b4b4(Te6edf3latestTb4b4b4, Te6edf3latestTb4b4b4)
Tff7b72assert Te6edf3schema_version_restorableTb4b4b4(T79c0ff0Tb4b4b4, Te6edf3latestTb4b4b4)
Tff7b72assert Tff7b72not Te6edf3schema_version_restorableTb4b4b4(Te6edf3latest Tff7b72+ T79c0ff1Tb4b4b4, Te6edf3latestTb4b4b4)
Tff7b72assert Tff7b72not Te6edf3schema_version_restorableTb4b4b4(Tff7b72NoneTb4b4b4, Te6edf3latestTb4b4b4)


Tff7b72def Td2a8fftest_infer_version_hint_from_pre_migrate_nameTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3name Tff7b72= Ta5d6fffTa5d6ff"Tffd700{Te6edf3PRE_MIGRATE_BACKUP_PREFIXTffd700}Ta5d6ffv52-to-v53-20260101-120000.zipTa5d6ff"
Tff7b72assert Te6edf3infer_version_hint_from_backup_nameTb4b4b4(Te6edf3nameTb4b4b4) Tff7b72== T79c0ff53
Tff7b72assert Te6edf3infer_version_hint_from_backup_nameTb4b4b4(Ta5d6ff"Ta5d6ffbackup-2026.zipTa5d6ff"Tb4b4b4) Tff7b72is Tff7b72None


Tff7b72def Td2a8fftest_pick_compatible_backup_skips_too_new_and_suspiciousTb4b4b4(Te6edf3tmp_pathTb4b4b4)Tb4b4b4:
Te6edf3temp_dir Tff7b72= Tffa657strTb4b4b4(Te6edf3tmp_pathTb4b4b4)
Te6edf3db_path Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3temp_dirTb4b4b4, Ta5d6ff"Ta5d6ffdatabase.dbTa5d6ff"Tb4b4b4)
Te6edf3db Tff7b72= Te6edf3DatabaseTb4b4b4(Te6edf3db_pathTb4b4b4)
Te6edf3dbTff7b72.Td2a8ffinitializeTb4b4b4(Tb4b4b4)
Te6edf3dbTff7b72.Td2a8ffproviderTff7b72.Td2a8ffexecuteTb4b4b4(
Ta5d6ff"Ta5d6ffINSERT INTO config (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.valueTa5d6ff"Tb4b4b4,
Tb4b4b4(Ta5d6ff"Ta5d6ffmarkerTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffpick-testTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3dbTff7b72.Td2a8ffclose_allTb4b4b4(Tb4b4b4)

Te6edf3backup_dir Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3temp_dirTb4b4b4, Ta5d6ff"Ta5d6ffdatabase-backupsTa5d6ff"Tb4b4b4)
Te6edf3osTff7b72.Td2a8ffmakedirsTb4b4b4(Te6edf3backup_dirTb4b4b4)
Te6edf3good Tff7b72= Te6edf3dbTff7b72.Td2a8ffbackup_databaseTb4b4b4(Te6edf3temp_dirTb4b4b4)
Tff7b72assert Te6edf3goodTb4b4b4[Ta5d6ff"Ta5d6ffpathTa5d6ff"Tb4b4b4]

Te6edf3too_new_path Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3backup_dirTb4b4b4, Ta5d6ff"Ta5d6ffbackup-too-new.zipTa5d6ff"Tb4b4b4)
Te6edf3db2 Tff7b72= Te6edf3DatabaseTb4b4b4(Te6edf3db_pathTb4b4b4)
Te6edf3db2Tff7b72.Td2a8ffinitializeTb4b4b4(Tb4b4b4)
Te6edf3db2Tff7b72.Td2a8ffproviderTff7b72.Td2a8ffexecuteTb4b4b4(
Ta5d6ff"Ta5d6ffUPDATE config SET value = ? WHERE key = ?Ta5d6ff"Tb4b4b4,
Tb4b4b4(Tffa657strTb4b4b4(Te6edf3DatabaseSchemaTff7b72.Td2a8ffLATEST_VERSION Tff7b72+ T79c0ff1Tb4b4b4)Tb4b4b4, Ta5d6ff"Ta5d6ffdatabase_versionTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3db2Tff7b72.Td2a8ffclose_allTb4b4b4(Tb4b4b4)
Te6edf3too_new Tff7b72= Te6edf3DatabaseTb4b4b4(Te6edf3db_pathTb4b4b4)
Te6edf3too_newTff7b72.Td2a8ffbackup_databaseTb4b4b4(Te6edf3temp_dirTb4b4b4, Te6edf3backup_pathTff7b72=Te6edf3too_new_pathTb4b4b4)
Te6edf3too_newTff7b72.Td2a8ffclose_allTb4b4b4(Tb4b4b4)

Te6edf3suspicious_path Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3backup_dirTb4b4b4, Ta5d6ff"Ta5d6ffbackup-SUSPICIOUS-test.zipTa5d6ff"Tb4b4b4)
Tff7b72with Tffa657openTb4b4b4(Te6edf3suspicious_pathTb4b4b4, Ta5d6ff"Ta5d6ffwbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3handleTb4b4b4:
Te6edf3handleTff7b72.Td2a8ffwriteTb4b4b4(Ta5d6ffbTa5d6ff"Ta5d6ffnot-a-real-zipTa5d6ff"Tb4b4b4)

Te6edf3picked Tff7b72= Te6edf3pick_compatible_backupTb4b4b4(Te6edf3temp_dirTb4b4b4, Te6edf3DatabaseSchemaTff7b72.Td2a8ffLATEST_VERSIONTb4b4b4)
Tff7b72assert Te6edf3picked Tff7b72is Tff7b72not Tff7b72None
Tff7b72assert Te6edf3pickedTb4b4b4[Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4] Tff7b72== Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffbasenameTb4b4b4(Te6edf3goodTb4b4b4[Ta5d6ff"Ta5d6ffpathTa5d6ff"Tb4b4b4]Tb4b4b4)
Tff7b72assert Te6edf3pickedTb4b4b4[Ta5d6ff"Ta5d6ffdatabase_versionTa5d6ff"Tb4b4b4] Tff7b72== Te6edf3DatabaseSchemaTff7b72.Td2a8ffLATEST_VERSION

Te6edf3probe Tff7b72= Te6edf3probe_backup_zipTb4b4b4(Te6edf3goodTb4b4b4[Ta5d6ff"Ta5d6ffpathTa5d6ff"Tb4b4b4]Tb4b4b4)
Tff7b72assert Te6edf3probeTb4b4b4[Ta5d6ff"Ta5d6ffquick_checkTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffokTa5d6ff"
Tff7b72assert Te6edf3probeTb4b4b4[Ta5d6ff"Ta5d6ffversionTa5d6ff"Tb4b4b4] Tff7b72== Te6edf3DatabaseSchemaTff7b72.Td2a8ffLATEST_VERSION


Tff7b72def Td2a8fftest_pick_compatible_backup_prefers_healthy_over_suspiciousTb4b4b4(Te6edf3tmp_pathTb4b4b4)Tb4b4b4:
Te6edf3temp_dir Tff7b72= Tffa657strTb4b4b4(Te6edf3tmp_pathTb4b4b4)
Te6edf3db_path Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3temp_dirTb4b4b4, Ta5d6ff"Ta5d6ffdatabase.dbTa5d6ff"Tb4b4b4)
Te6edf3db Tff7b72= Te6edf3DatabaseTb4b4b4(Te6edf3db_pathTb4b4b4)
Te6edf3dbTff7b72.Td2a8ffinitializeTb4b4b4(Tb4b4b4)
Te6edf3good Tff7b72= Te6edf3dbTff7b72.Td2a8ffbackup_databaseTb4b4b4(Te6edf3temp_dirTb4b4b4)
Te6edf3dbTff7b72.Td2a8ffclose_allTb4b4b4(Tb4b4b4)

Te6edf3backup_dir Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3temp_dirTb4b4b4, Ta5d6ff"Ta5d6ffdatabase-backupsTa5d6ff"Tb4b4b4)
Te6edf3suspicious_path Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3backup_dirTb4b4b4, Ta5d6ff"Ta5d6ffbackup-SUSPICIOUS-only.zipTa5d6ff"Tb4b4b4)
Tff7b72with Tffa657openTb4b4b4(Te6edf3suspicious_pathTb4b4b4, Ta5d6ff"Ta5d6ffwbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3handleTb4b4b4:
Te6edf3handleTff7b72.Td2a8ffwriteTb4b4b4(Ta5d6ffbTa5d6ff"Ta5d6ffPKTffea00\x03Tffea00\x04Ta5d6ff"Tb4b4b4)
T8b949e# corrupt zip still listed but should not win over good backup

Te6edf3picked Tff7b72= Te6edf3pick_compatible_backupTb4b4b4(Te6edf3temp_dirTb4b4b4, Te6edf3DatabaseSchemaTff7b72.Td2a8ffLATEST_VERSIONTb4b4b4)
Tff7b72assert Te6edf3picked Tff7b72is Tff7b72not Tff7b72None
Tff7b72assert Te6edf3pickedTb4b4b4[Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4] Tff7b72== Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffbasenameTb4b4b4(Te6edf3goodTb4b4b4[Ta5d6ff"Ta5d6ffpathTa5d6ff"Tb4b4b4]Tb4b4b4)


Tff7b72def Td2a8fftest_run_auto_database_recover_restores_when_backup_existsTb4b4b4(Te6edf3tmp_pathTb4b4b4)Tb4b4b4:
Te6edf3temp_dir Tff7b72= Tffa657strTb4b4b4(Te6edf3tmp_pathTb4b4b4)
Te6edf3db_path Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3temp_dirTb4b4b4, Ta5d6ff"Ta5d6ffdatabase.dbTa5d6ff"Tb4b4b4)
Te6edf3db Tff7b72= Te6edf3DatabaseTb4b4b4(Te6edf3db_pathTb4b4b4)
Te6edf3dbTff7b72.Td2a8ffinitializeTb4b4b4(Tb4b4b4)
Te6edf3backup_info Tff7b72= Te6edf3dbTff7b72.Td2a8ffbackup_databaseTb4b4b4(Te6edf3temp_dirTb4b4b4)
Te6edf3dbTff7b72.Td2a8ffclose_allTb4b4b4(Tb4b4b4)

Te6edf3restored_pathsTb4b4b4: Tffa657listTb4b4b4[Tffa657strTb4b4b4] Tff7b72= Tb4b4b4[Tb4b4b4]

Tff7b72def Td2a8ffrestore_fnTb4b4b4(Te6edf3pathTb4b4b4: Tffa657strTb4b4b4) Tff7b72-Tff7b72> Tffa657dictTb4b4b4:
Te6edf3restored_pathsTff7b72.Td2a8ffappendTb4b4b4(Te6edf3pathTb4b4b4)
Tff7b72return Tb4b4b4{Ta5d6ff"Ta5d6ffpathTa5d6ff"Tb4b4b4: Te6edf3pathTb4b4b4, Ta5d6ff"Ta5d6ffrestoredTa5d6ff"Tb4b4b4: Tff7b72TrueTb4b4b4}

Te6edf3result Tff7b72= Te6edf3run_auto_database_recoverTb4b4b4(
Te6edf3temp_dirTb4b4b4,
Te6edf3db_pathTb4b4b4,
Te6edf3DatabaseSchemaTff7b72.Td2a8ffLATEST_VERSIONTb4b4b4,
Te6edf3restore_fnTb4b4b4,
Te6edf3sqlite_recover_fnTff7b72=Tff7b72lambdaTb4b4b4: Tb4b4b4{Ta5d6ff"Ta5d6ffactionsTa5d6ff"Tb4b4b4: Tb4b4b4[Tb4b4b4]Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tff7b72assert Te6edf3resultTb4b4b4[Ta5d6ff"Ta5d6ffstrategyTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffrestore_backupTa5d6ff"
Tff7b72assert Te6edf3restored_paths Tff7b72== Tb4b4b4[Te6edf3backup_infoTb4b4b4[Ta5d6ff"Ta5d6ffpathTa5d6ff"Tb4b4b4]Tb4b4b4]
Tff7b72assert Te6edf3resultTb4b4b4[Ta5d6ff"Ta5d6ffrequires_relaunchTa5d6ff"Tb4b4b4] Tff7b72is Tff7b72True


Tff7b72def Td2a8fftest_run_auto_database_recover_falls_back_to_sqliteTb4b4b4(Te6edf3tmp_pathTb4b4b4)Tb4b4b4:
Te6edf3temp_dir Tff7b72= Tffa657strTb4b4b4(Te6edf3tmp_pathTb4b4b4)
Te6edf3db_path Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3temp_dirTb4b4b4, Ta5d6ff"Ta5d6ffdatabase.dbTa5d6ff"Tb4b4b4)
Te6edf3db Tff7b72= Te6edf3DatabaseTb4b4b4(Te6edf3db_pathTb4b4b4)
Te6edf3dbTff7b72.Td2a8ffinitializeTb4b4b4(Tb4b4b4)
Te6edf3dbTff7b72.Td2a8ffclose_allTb4b4b4(Tb4b4b4)

Te6edf3sqlite_called Tff7b72= Tff7b72False

Tff7b72def Td2a8ffrestore_fnTb4b4b4(Te6edf3_pathTb4b4b4: Tffa657strTb4b4b4) Tff7b72-Tff7b72> Tffa657dictTb4b4b4:
Tff7b72raise Tf85149AssertionErrorTb4b4b4(Ta5d6ff"Ta5d6ffrestore should not run without backupsTa5d6ff"Tb4b4b4)

Tff7b72def Td2a8ffsqlite_fnTb4b4b4(Tb4b4b4) Tff7b72-Tff7b72> Tffa657dictTb4b4b4:
Tff7b72nonlocal Te6edf3sqlite_called
Te6edf3sqlite_called Tff7b72= Tff7b72True
Tff7b72return Tb4b4b4{Ta5d6ff"Ta5d6ffactionsTa5d6ff"Tb4b4b4: Tb4b4b4[Tb4b4b4{Ta5d6ff"Ta5d6ffstepTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffwal_checkpointTa5d6ff"Tb4b4b4}Tb4b4b4]Tb4b4b4}

Te6edf3result Tff7b72= Te6edf3run_auto_database_recoverTb4b4b4(
Te6edf3temp_dirTb4b4b4,
Te6edf3db_pathTb4b4b4,
Te6edf3DatabaseSchemaTff7b72.Td2a8ffLATEST_VERSIONTb4b4b4,
Te6edf3restore_fnTb4b4b4,
Te6edf3sqlite_recover_fnTff7b72=Te6edf3sqlite_fnTb4b4b4,
Tb4b4b4)
Tff7b72assert Te6edf3sqlite_called
Tff7b72assert Te6edf3resultTb4b4b4[Ta5d6ff"Ta5d6ffstrategyTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffsqlite_recoveryTa5d6ff"
Tff7b72assert Te6edf3resultTb4b4b4[Ta5d6ff"Ta5d6ffrequires_relaunchTa5d6ff"Tb4b4b4] Tff7b72is Tff7b72False


Tff7b72def Td2a8fftest_run_auto_database_recover_none_without_backups_or_dbTb4b4b4(Te6edf3tmp_pathTb4b4b4)Tb4b4b4:
Te6edf3temp_dir Tff7b72= Tffa657strTb4b4b4(Te6edf3tmp_pathTb4b4b4)
Te6edf3result Tff7b72= Te6edf3run_auto_database_recoverTb4b4b4(
Te6edf3temp_dirTb4b4b4,
Tff7b72NoneTb4b4b4,
Te6edf3DatabaseSchemaTff7b72.Td2a8ffLATEST_VERSIONTb4b4b4,
Tff7b72lambda Te6edf3_pTb4b4b4: Tb4b4b4{Tb4b4b4}Tb4b4b4,
Te6edf3sqlite_recover_fnTff7b72=Tff7b72NoneTb4b4b4,
Tb4b4b4)
Tff7b72assert Te6edf3resultTb4b4b4[Ta5d6ff"Ta5d6ffstrategyTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffnoneTa5d6ff"

Served by rngit 1.4.2 - Generated in 0.02s